This tutorial follows from our introduction to multivariate linear models, extending it by using multivariate linear mixed models.

Useful packages:

library(MCMCglmm)
library(lme4)
library(brms)
library(tidyr)
library(dplyr)
library(corrplot)
library(broom.mixed)
library(dotwhisker)
library(ggplot2); theme_set(theme_bw())

Get data:

data_url <- "http://datadryad.org/bitstream/handle/10255/dryad.8377/dll.csv"
if (!file.exists("dll.csv")) {
    download.file(data_url,dest="dll.csv")
}
dll_data <- read.csv("dll.csv")
## make temp a factor (25 vs 30 degrees)
dll_data$temp <- factor(dll_data$temp)
## scale relevant variables (fancier but less repetition than previously)
morph_vars <- c("femur","tibia","tarsus","SCT")
morph_vars_sc <- paste(morph_vars,"s",sep="_")
dll_data2 <- dll_data
## c() drops unwanted structure from the results of scale()
for (i in 1:length(morph_vars)) {
    dll_data2[[morph_vars_sc[i]]] <- c(scale(dll_data[[morph_vars[i]]]))
}

0.1 Mixed models

The previous expression for the multivariate model was

\[ \mathbf{Y} = \mathbf{XB} + \mathbf{E} \]

In contrast, the expression for the mixed model is

\[ y = \mathbf{X\beta} + \mathbf{Zb} + \epsilon \]

where \(\mathbf{b}\) is a set of Gaussian variables with a variance-covariance matrix \(\mathbf{\Sigma}\) which we estimate.

Suppose we have observations of \(m\) individuals, with \(p\) different observations (traits, or time points, or types of measurement, or …) for each individual. The way we’re going to make this work is to expand (“melt”, or gather() if we’re using tidyr) the data set to be \(mp\) observations long, then treat each individual (which was previously a single row of the data set but now comprises \(p\) rows) as a group (we’ll call this units):

0.2 A trick to do multivariate mixed models using lme4

lme4 does not (currently) have a natural syntax for multivariate responses, however, as I eluded to in class, there is an important relationship between multivariate response models and so called “repeated” measures (or longitudinal) models. As such we can use a few tricks to estimate the model in lme4. Below this, I will go through the same model using MCMCglmm, which is a library which has a more natural syntax for such multivariate responses, but is explictly Bayesian, so you need to provide prior distributions.

0.2.1 melting code for lme4

What we need to first do (for lme4) is to generate a single column that represents the numeric values for our response traits, and then a second variable that stores the trait type.

melting

dll_melt <- (dll_data2
    %>% select(-c(femur,tibia,tarsus,SCT))  ## drop unscaled vars
    %>% mutate(units=factor(1:n()))
    %>% gather(trait,value, -c(units,replicate,line,genotype,temp))
    %>% drop_na()
    %>% arrange(units)
)
saveRDS(dll_melt, file="dll_melt.rds")

And we can take a look at how this has changed the structure of the data from a “wide” format to a long format

head(dll_data) # original wide
##   replicate   line genotype temp femur tibia tarsus SCT
## 1         1 line-1      Dll   25 0.590 0.499  0.219   9
## 2         1 line-1      Dll   25 0.550 0.501  0.214  13
## 3         1 line-1      Dll   25 0.588 0.488  0.211  11
## 4         1 line-1      Dll   25 0.588 0.515  0.211  NA
## 5         1 line-1      Dll   25 0.596 0.502  0.207  12
## 6         1 line-1      Dll   25 0.577 0.499  0.207  14

To the long format

head(dll_melt)
##   replicate   line genotype temp units    trait  value
## 1         1 line-1      Dll   25     1  femur_s  1.514
## 2         1 line-1      Dll   25     1  tibia_s  0.597
## 3         1 line-1      Dll   25     1 tarsus_s  1.751
## 4         1 line-1      Dll   25     1    SCT_s -1.222
## 5         1 line-1      Dll   25     2  femur_s  0.138
## 6         1 line-1      Dll   25     2  tibia_s  0.654

0.3 lmer fit

We can now go ahead and fit the model where we need to include trait as a predictor variable (where each trait is now a “repeated measure” from a particular subject/individual)

t1 <- system.time(
    lmer1 <- lmer(value ~ trait:(genotype*temp) - 1 +
                      (trait-1|line) + (trait-1|units),
                  data=dll_melt,
                  control=lmerControl(optCtrl=list(ftol_abs=1e-10),
                                      optimizer="bobyqa",
                                      check.nobs.vs.nlev="ignore",
                                      check.nobs.vs.nRE="ignore"))
)
## Warning in (function (npt = min(n + 2L, 2L * n), rhobeg = NA, rhoend =
## NA, : unused control arguments ignored

0.4 lme4: fixed-effects formula

0.5 lme4: random-effects formula

0.6 Notes on lme4 results

0.7 lme4: random-effects var/cov

all(abs(getME(lmer1,"theta"))>1e-4) ## check for singularity (OK in this case)
## [1] TRUE
VarCorr(lmer1)
##  Groups   Name          Std.Dev. Corr          
##  units    traitfemur_s  0.654                  
##           traitSCT_s    0.728    0.05          
##           traittarsus_s 0.565    0.58 0.20     
##           traittibia_s  0.670    0.91 0.12 0.47
##  line     traitfemur_s  0.489                  
##           traitSCT_s    0.392    0.14          
##           traittarsus_s 0.462    0.81 0.37     
##           traittibia_s  0.473    0.87 0.22 0.83
##  Residual               0.462

0.8 lme4: correlation plot

par(mfrow=c(1,2))
vv1 <- VarCorr(lmer1)
## fix unit variance-covariance by adding residual variance:
diag(vv1$units) <- diag(vv1$units)+sigma(lmer1)^2
corrplot.mixed(cov2cor(vv1$line),upper="ellipse")
corrplot.mixed(cov2cor(vv1$units),upper="ellipse")

Correlations of traits across lines are stronger than correlations within individuals. In both cases correlations are all positive (i.e. first axis of variation is size variation?)

0.9 lme4: coefficient plot

cc1 <- tidy(lmer1,effect="fixed") %>%
  tidyr::separate(term,into=c("trait","fixeff"),extra="merge",
                  remove=FALSE)
dwplot(cc1)+facet_wrap(~fixeff,scale="free",ncol=2)+
  geom_vline(xintercept=0,lty=2)

These results tell approximately the same story (coefficients are consistent across traits within a fixed effect, e.g. effect of higher temperature is to reduce scores on all traits).

0.10 lme4: random effects

This is very slow, you probably don’t want to evaluate it on your computer

cc2 <- tidy(lmer1,
            effect = "ran_pars",
            conf.int = TRUE,
            conf.method = "profile",
            parallel="multicore",
            ncpus=2)

1 MCMCglmm

Another option is the MCMCglmm package, which has a natural interface for general multivariate mixed models. It takes a while to get used to the interface, but here is an example. Please check out here for more information about the package, and here for an overview of how to use it.

First I find it easier (given the interface of MCMCglmm) to create a formula with the response variables and predictors. This is only for the fixed effects part of the model.

fmla.MMLM1  <- cbind(femur_s, tibia_s, tarsus_s, SCT_s) ~
    trait:(genotype*temp) - 1

Now we need to let MCMCglmm know which family (i.e. distribution) the response variables are. Since all are normal (Gaussian), we can specify it the following way.

fam.test <- rep("gaussian", 4 )

Since MCMCglmm is fundamentally a Bayesian approach, it needs a prior. If you provide no prior by default, it tries a “flat” prior, although this rarely works. In this case I am providing a not-quite-flat prior, but just for the random effects of line and for the residual variances (could also provide them for the fixed effects). Choosing priors for variances and covariances can sometimes be tricky, and for the moment is too much to chew on in this class, so we will use the default prior distributions (inverse-Wishart is what it is called if you really care). If you want to get deep into this, come chat with me. I also have some simple tutorials where I draw out the effects of various common priors for variances and covariances.

prior.model.1 <- list( R = list(V=diag(4)/4, nu=0.004),  
                       G = list(G1=list(V=diag(4)/4, nu=0.004)))

Let’s take a quick look at the prior

prior.model.1
## $R
## $R$V
##      [,1] [,2] [,3] [,4]
## [1,] 0.25 0.00 0.00 0.00
## [2,] 0.00 0.25 0.00 0.00
## [3,] 0.00 0.00 0.25 0.00
## [4,] 0.00 0.00 0.00 0.25
## 
## $R$nu
## [1] 0.004
## 
## 
## $G
## $G$G1
## $G$G1$V
##      [,1] [,2] [,3] [,4]
## [1,] 0.25 0.00 0.00 0.00
## [2,] 0.00 0.25 0.00 0.00
## [3,] 0.00 0.00 0.25 0.00
## [4,] 0.00 0.00 0.00 0.25
## 
## $G$G1$nu
## [1] 0.004

The R matrix prior is for the residuals. This is \(\mathbf{R}_{4,4}\) as we have 4 traits in the VCV matrix. We have have non-zero variances for each trait as the mode for the prior, and 0 for covariances. However this is a weak prior, so even small amounts of data will largely overcome the pull of the prior. Another sensible approach we have used is to make the prior proportional to the overall observed VCV, as there is a large literature on the proportionality of covariance matrices for morphology. This may not be sensible for other types of multivariate response measures.

##,depends.on=c("prior","mod_fm","get_data")}
t2 <- system.time(
    MMLM1.fit <- MCMCglmm(fmla.MMLM1,
                          random=~ us(trait):line, 
                          rcov=~ us(trait):units,
                          prior=  prior.model.1,
                          data= dll_data2, 
                          family = fam.test, 
                          nitt= 10000, burnin= 2000, thin=10)
)
## Warning: 'cBind' is deprecated.
##  Since R version 3.2.0, base's cbind() should work fine with S4 objects

1.1 MCMCglmm specification: fixed effects

  • fmla.MMLM1 is the formula object we created above
  • it looks like the lmer formula
  • the trait term is a reserved word in MCMCglmm, letting it know we want to fit a multivariate mixed model
  • MCMCglmm automatically melts the data for us (and assigns the name trait the same way we did manually above)

1.2 MCMCglmm: random effects

  • random=~us(trait):line asks MCMCglmm to fit an unstructured covariance matrix for the line term (i.e the different wild type genotypes we are examining).- “Unstructured” means we are estimating the complete 4 x 4 matrix of covariances (= 4*5/2 = 10 elements total)
  • equivalent to (trait-1|line) in lmer model
  • MCMCglmm also automatically adds a units
  • rcov=~us(trait):units = (trait-1|units)
  • MCMCglmm offers a few other options for variance-covariance structures

1.3 MCMCglmm: other options

The nitt is how many iterations for the MCMC we want to perform, and the burnin is how many should be ignored at the beginning of the random walk.

1.4 MCMCglmm: diagnostics

The fit takes 22 seconds.

Normally we would spend a fair bit of time on diagnostics of the MCMC, but for now we will just quickly check the trace plots and autocorrelation.

In the fitted object $Sol is for solution, which is the term used for fixed effects in MCMCglmm. $VCV is for the variance-covariance matrix.

library(lattice)
xyplot(MMLM1.fit$Sol[,1:4])

xyplot(MMLM1.fit$Sol[,13:16])

acf(MMLM1.fit$Sol[,1:2])

xyplot(MMLM1.fit$VCV[,1:4])

acf(MMLM1.fit$VCV[,1:3])

Nothing terribly worrying.

summary(MMLM1.fit)
## 
##  Iterations = 2001:9991
##  Thinning interval  = 10
##  Sample size  = 800 
## 
##  DIC: 17450 
## 
##  G-structure:  ~us(trait):line
## 
##                                  post.mean l-95% CI u-95% CI eff.samp
## traitfemur_s:traitfemur_s.line      0.3006   0.1452    0.506      800
## traittibia_s:traitfemur_s.line      0.2527   0.1045    0.428      800
## traittarsus_s:traitfemur_s.line     0.2311   0.0875    0.397      904
## traitSCT_s:traitfemur_s.line        0.0329  -0.0864    0.134      800
## traitfemur_s:traittibia_s.line      0.2527   0.1045    0.428      800
## traittibia_s:traittibia_s.line      0.2789   0.1286    0.460      800
## traittarsus_s:traittibia_s.line     0.2279   0.0959    0.407      901
## traitSCT_s:traittibia_s.line        0.0505  -0.0434    0.169     1127
## traitfemur_s:traittarsus_s.line     0.2311   0.0875    0.397      904
## traittibia_s:traittarsus_s.line     0.2279   0.0959    0.407      901
## traittarsus_s:traittarsus_s.line    0.2689   0.1198    0.453      895
## traitSCT_s:traittarsus_s.line       0.0827  -0.0262    0.208     1028
## traitfemur_s:traitSCT_s.line        0.0329  -0.0864    0.134      800
## traittibia_s:traitSCT_s.line        0.0505  -0.0434    0.169     1127
## traittarsus_s:traitSCT_s.line       0.0827  -0.0262    0.208     1028
## traitSCT_s:traitSCT_s.line          0.1942   0.0850    0.348      800
## 
##  R-structure:  ~us(trait):units
## 
##                                   post.mean l-95% CI u-95% CI eff.samp
## traitfemur_s:traitfemur_s.units      0.6434  0.60477   0.6810      800
## traittibia_s:traitfemur_s.units      0.4014  0.36591   0.4341     1097
## traittarsus_s:traitfemur_s.units     0.2145  0.18655   0.2436      800
## traitSCT_s:traitfemur_s.units        0.0259 -0.00364   0.0588      800
## traitfemur_s:traittibia_s.units      0.4014  0.36591   0.4341     1097
## traittibia_s:traittibia_s.units      0.6654  0.62932   0.7095      800
## traittarsus_s:traittibia_s.units     0.1797  0.15195   0.2069      800
## traitSCT_s:traittibia_s.units        0.0600  0.03118   0.0946      800
## traitfemur_s:traittarsus_s.units     0.2145  0.18655   0.2436      800
## traittibia_s:traittarsus_s.units     0.1797  0.15195   0.2069      800
## traittarsus_s:traittarsus_s.units    0.5353  0.50093   0.5678      965
## traitSCT_s:traittarsus_s.units       0.0842  0.05505   0.1144     1009
## traitfemur_s:traitSCT_s.units        0.0259 -0.00364   0.0588      800
## traittibia_s:traitSCT_s.units        0.0600  0.03118   0.0946      800
## traittarsus_s:traitSCT_s.units       0.0842  0.05505   0.1144     1009
## traitSCT_s:traitSCT_s.units          0.7465  0.69744   0.7936      800
## 
##  Location effects: cbind(femur_s, tibia_s, tarsus_s, SCT_s) ~ trait:(genotype * temp) - 1 
## 
##                                 post.mean l-95% CI u-95% CI eff.samp
## traitfemur_s:genotypeDll           0.5052   0.2861   0.7145      800
## traittibia_s:genotypeDll           0.6371   0.4266   0.8550      800
## traittarsus_s:genotypeDll          0.6096   0.4110   0.8131      800
## traitSCT_s:genotypeDll             0.6787   0.5152   0.8867      800
## traitfemur_s:genotypewt            0.1758  -0.0308   0.4051      800
## traittibia_s:genotypewt            0.0175  -0.2004   0.2175      800
## traittarsus_s:genotypewt           0.4395   0.2454   0.6401      800
## traitSCT_s:genotypewt             -0.0806  -0.2480   0.1103      800
## traitfemur_s:temp30               -0.8356  -0.9399  -0.7194      922
## traittibia_s:temp30               -0.8097  -0.9140  -0.6971      642
## traittarsus_s:temp30              -1.2370  -1.3327  -1.1423     1026
## traitSCT_s:temp30                 -0.8383  -0.9493  -0.7152      800
## traitfemur_s:genotypewt:temp30     0.3587   0.2195   0.5022      800
## traittibia_s:genotypewt:temp30     0.4742   0.3228   0.6169      699
## traittarsus_s:genotypewt:temp30    0.5155   0.3894   0.6557      800
## traitSCT_s:genotypewt:temp30       0.7257   0.6052   0.8834      800
##                                  pMCMC   
## traitfemur_s:genotypeDll        <0.001 **
## traittibia_s:genotypeDll        <0.001 **
## traittarsus_s:genotypeDll       <0.001 **
## traitSCT_s:genotypeDll          <0.001 **
## traitfemur_s:genotypewt           0.10   
## traittibia_s:genotypewt           0.85   
## traittarsus_s:genotypewt        <0.001 **
## traitSCT_s:genotypewt             0.38   
## traitfemur_s:temp30             <0.001 **
## traittibia_s:temp30             <0.001 **
## traittarsus_s:temp30            <0.001 **
## traitSCT_s:temp30               <0.001 **
## traitfemur_s:genotypewt:temp30  <0.001 **
## traittibia_s:genotypewt:temp30  <0.001 **
## traittarsus_s:genotypewt:temp30 <0.001 **
## traitSCT_s:genotypewt:temp30    <0.001 **
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Sometimes it is easier to look at the fixed and random effects separately.

summary(MMLM1.fit$Sol)
## 
## Iterations = 2001:9991
## Thinning interval = 10 
## Number of chains = 1 
## Sample size per chain = 800 
## 
## 1. Empirical mean and standard deviation for each variable,
##    plus standard error of the mean:
## 
##                                    Mean     SD Naive SE Time-series SE
## traitfemur_s:genotypeDll         0.5052 0.1138  0.00402        0.00402
## traittibia_s:genotypeDll         0.6371 0.1119  0.00396        0.00396
## traittarsus_s:genotypeDll        0.6096 0.1057  0.00374        0.00374
## traitSCT_s:genotypeDll           0.6787 0.0954  0.00337        0.00337
## traitfemur_s:genotypewt          0.1758 0.1121  0.00396        0.00396
## traittibia_s:genotypewt          0.0175 0.1107  0.00391        0.00391
## traittarsus_s:genotypewt         0.4395 0.1050  0.00371        0.00371
## traitSCT_s:genotypewt           -0.0806 0.0914  0.00323        0.00323
## traitfemur_s:temp30             -0.8356 0.0559  0.00198        0.00184
## traittibia_s:temp30             -0.8097 0.0559  0.00198        0.00220
## traittarsus_s:temp30            -1.2370 0.0510  0.00180        0.00159
## traitSCT_s:temp30               -0.8383 0.0587  0.00208        0.00208
## traitfemur_s:genotypewt:temp30   0.3587 0.0743  0.00263        0.00263
## traittibia_s:genotypewt:temp30   0.4742 0.0778  0.00275        0.00294
## traittarsus_s:genotypewt:temp30  0.5155 0.0671  0.00237        0.00237
## traitSCT_s:genotypewt:temp30     0.7257 0.0748  0.00265        0.00265
## 
## 2. Quantiles for each variable:
## 
##                                    2.5%     25%     50%     75%  97.5%
## traitfemur_s:genotypeDll         0.2861  0.4300  0.5035  0.5789  0.715
## traittibia_s:genotypeDll         0.4199  0.5621  0.6353  0.7142  0.854
## traittarsus_s:genotypeDll        0.4155  0.5404  0.6082  0.6748  0.822
## traitSCT_s:genotypeDll           0.4952  0.6124  0.6779  0.7396  0.877
## traitfemur_s:genotypewt         -0.0405  0.1024  0.1714  0.2526  0.395
## traittibia_s:genotypewt         -0.1864 -0.0568  0.0160  0.0906  0.233
## traittarsus_s:genotypewt         0.2469  0.3728  0.4388  0.5056  0.640
## traitSCT_s:genotypewt           -0.2541 -0.1435 -0.0818 -0.0193  0.103
## traitfemur_s:temp30             -0.9477 -0.8716 -0.8344 -0.7981 -0.723
## traittibia_s:temp30             -0.9176 -0.8490 -0.8108 -0.7697 -0.700
## traittarsus_s:temp30            -1.3327 -1.2718 -1.2381 -1.2017 -1.142
## traitSCT_s:temp30               -0.9601 -0.8741 -0.8356 -0.8001 -0.720
## traitfemur_s:genotypewt:temp30   0.2169  0.3083  0.3594  0.4081  0.501
## traittibia_s:genotypewt:temp30   0.3229  0.4179  0.4754  0.5286  0.617
## traittarsus_s:genotypewt:temp30  0.3787  0.4753  0.5175  0.5607  0.647
## traitSCT_s:genotypewt:temp30     0.5822  0.6725  0.7222  0.7799  0.874

And for the random effects.

summary(MMLM1.fit$VCV)
## 
## Iterations = 2001:9991
## Thinning interval = 10 
## Number of chains = 1 
## Sample size per chain = 800 
## 
## 1. Empirical mean and standard deviation for each variable,
##    plus standard error of the mean:
## 
##                                     Mean     SD Naive SE Time-series SE
## traitfemur_s:traitfemur_s.line    0.3006 0.1066 0.003769       0.003769
## traittibia_s:traitfemur_s.line    0.2527 0.0942 0.003330       0.003330
## traittarsus_s:traitfemur_s.line   0.2311 0.0884 0.003124       0.002940
## traitSCT_s:traitfemur_s.line      0.0329 0.0575 0.002032       0.002032
## traitfemur_s:traittibia_s.line    0.2527 0.0942 0.003330       0.003330
## traittibia_s:traittibia_s.line    0.2789 0.0951 0.003361       0.003361
## traittarsus_s:traittibia_s.line   0.2279 0.0848 0.003000       0.002827
## traitSCT_s:traittibia_s.line      0.0505 0.0557 0.001969       0.001659
## traitfemur_s:traittarsus_s.line   0.2311 0.0884 0.003124       0.002940
## traittibia_s:traittarsus_s.line   0.2279 0.0848 0.003000       0.002827
## traittarsus_s:traittarsus_s.line  0.2689 0.0929 0.003285       0.003107
## traitSCT_s:traittarsus_s.line     0.0827 0.0602 0.002130       0.001879
## traitfemur_s:traitSCT_s.line      0.0329 0.0575 0.002032       0.002032
## traittibia_s:traitSCT_s.line      0.0505 0.0557 0.001969       0.001659
## traittarsus_s:traitSCT_s.line     0.0827 0.0602 0.002130       0.001879
## traitSCT_s:traitSCT_s.line        0.1942 0.0726 0.002566       0.002566
## traitfemur_s:traitfemur_s.units   0.6434 0.0200 0.000708       0.000708
## traittibia_s:traitfemur_s.units   0.4014 0.0176 0.000623       0.000532
## traittarsus_s:traitfemur_s.units  0.2145 0.0149 0.000526       0.000526
## traitSCT_s:traitfemur_s.units     0.0259 0.0162 0.000573       0.000573
## traitfemur_s:traittibia_s.units   0.4014 0.0176 0.000623       0.000532
## traittibia_s:traittibia_s.units   0.6654 0.0212 0.000751       0.000751
## traittarsus_s:traittibia_s.units  0.1797 0.0144 0.000509       0.000509
## traitSCT_s:traittibia_s.units     0.0600 0.0168 0.000593       0.000593
## traitfemur_s:traittarsus_s.units  0.2145 0.0149 0.000526       0.000526
## traittibia_s:traittarsus_s.units  0.1797 0.0144 0.000509       0.000509
## traittarsus_s:traittarsus_s.units 0.5353 0.0173 0.000612       0.000557
## traitSCT_s:traittarsus_s.units    0.0842 0.0153 0.000540       0.000481
## traitfemur_s:traitSCT_s.units     0.0259 0.0162 0.000573       0.000573
## traittibia_s:traitSCT_s.units     0.0600 0.0168 0.000593       0.000593
## traittarsus_s:traitSCT_s.units    0.0842 0.0153 0.000540       0.000481
## traitSCT_s:traitSCT_s.units       0.7465 0.0249 0.000881       0.000881
## 
## 2. Quantiles for each variable:
## 
##                                       2.5%      25%    50%    75%  97.5%
## traitfemur_s:traitfemur_s.line     0.15685  0.22944 0.2783 0.3484 0.5628
## traittibia_s:traitfemur_s.line     0.12691  0.19184 0.2344 0.2968 0.4684
## traittarsus_s:traitfemur_s.line    0.10633  0.17203 0.2151 0.2714 0.4496
## traitSCT_s:traitfemur_s.line      -0.06737 -0.00465 0.0293 0.0669 0.1671
## traitfemur_s:traittibia_s.line     0.12691  0.19184 0.2344 0.2968 0.4684
## traittibia_s:traittibia_s.line     0.15771  0.21287 0.2613 0.3194 0.5026
## traittarsus_s:traittibia_s.line    0.10873  0.16867 0.2113 0.2672 0.4262
## traitSCT_s:traittibia_s.line      -0.04269  0.01587 0.0438 0.0796 0.1734
## traitfemur_s:traittarsus_s.line    0.10633  0.17203 0.2151 0.2714 0.4496
## traittibia_s:traittarsus_s.line    0.10873  0.16867 0.2113 0.2672 0.4262
## traittarsus_s:traittarsus_s.line   0.14496  0.20449 0.2474 0.3124 0.5123
## traitSCT_s:traittarsus_s.line     -0.01289  0.04464 0.0746 0.1133 0.2263
## traitfemur_s:traitSCT_s.line      -0.06737 -0.00465 0.0293 0.0669 0.1671
## traittibia_s:traitSCT_s.line      -0.04269  0.01587 0.0438 0.0796 0.1734
## traittarsus_s:traitSCT_s.line     -0.01289  0.04464 0.0746 0.1133 0.2263
## traitSCT_s:traitSCT_s.line         0.09629  0.14248 0.1793 0.2252 0.3889
## traitfemur_s:traitfemur_s.units    0.60735  0.62944 0.6428 0.6569 0.6835
## traittibia_s:traitfemur_s.units    0.36902  0.38975 0.4010 0.4125 0.4387
## traittarsus_s:traitfemur_s.units   0.18463  0.20476 0.2145 0.2251 0.2432
## traitSCT_s:traitfemur_s.units     -0.00473  0.01532 0.0260 0.0364 0.0577
## traitfemur_s:traittibia_s.units    0.36902  0.38975 0.4010 0.4125 0.4387
## traittibia_s:traittibia_s.units    0.62795  0.65055 0.6641 0.6796 0.7083
## traittarsus_s:traittibia_s.units   0.15204  0.16984 0.1796 0.1898 0.2069
## traitSCT_s:traittibia_s.units      0.02842  0.04898 0.0604 0.0710 0.0925
## traitfemur_s:traittarsus_s.units   0.18463  0.20476 0.2145 0.2251 0.2432
## traittibia_s:traittarsus_s.units   0.15204  0.16984 0.1796 0.1898 0.2069
## traittarsus_s:traittarsus_s.units  0.50191  0.52361 0.5354 0.5472 0.5689
## traitSCT_s:traittarsus_s.units     0.05395  0.07446 0.0840 0.0943 0.1133
## traitfemur_s:traitSCT_s.units     -0.00473  0.01532 0.0260 0.0364 0.0577
## traittibia_s:traitSCT_s.units      0.02842  0.04898 0.0604 0.0710 0.0925
## traittarsus_s:traitSCT_s.units     0.05395  0.07446 0.0840 0.0943 0.1133
## traitSCT_s:traitSCT_s.units        0.69827  0.72984 0.7457 0.7627 0.7961

This is not the most friendly output, and it takes a while to get used to. However, we can see that we still have evidence for something interesting going, and we could extract the vectors of effects as we did above.

let’s look at the VCV matrix for the random effects of line in a slightly clearer way (as a matrix)

##' extract variance-covariance matrices for MCMCglmm objects
##' does not (yet) set cor, stddev, residual-var attributes
##' may be fragile: depends on group vars not having dots in them?
VarCorr.MCMCglmm <- function(object, ...) {
    s <- summary(object$VCV)$statistics[,"Mean"]
    grps <- gsub("^[^.]+\\.([[:alnum:]]+)$","\\1",names(s))
    ss <- split(s,grps)
    getVC <- function(x) {
        nms <- gsub("^([^.]+)\\.[[:alnum:]]+$","\\1",names(x))
        n <- length(nms)
        L <- round(sqrt(n))
        dimnms <- gsub("^([^:]+):.*$","\\1",nms[1:L])
        return(matrix(x,dimnames=list(dimnms,dimnms),
                      nrow=L))
    }
    r <- setNames(lapply(ss,getVC),unique(grps))
    return(r)
}
vv <- VarCorr(MMLM1.fit)
par(mfrow=c(1,2))
corrplot.mixed(cov2cor(vv$line),upper="ellipse")
corrplot.mixed(cov2cor(vv$units),upper="ellipse")

  • among-line effects are very similar to lme4 estimates (variables are in a different order)
  • among-individual effects a

This is only a taste of what to do, and after this we could start asking questions about this genetic variance co-variance matrix.

Compare fixed effects:

tt <- tidy(MMLM1.fit)
tt2 <- tidy(lmer1)
tt_comb <- bind_rows(lmer=tt,MCMCglmm=tt2,.id="model") %>%
    filter(effect=="fixed")
dwplot(tt_comb)+geom_vline(xintercept=0,lty=2)

1.5 Pros and cons

  • MCMCglmm: Bayesian
    • easier to get various kinds of confidence intervals
    • flexible priors
    • more flexible variance structures
    • multiple response types within a unit (e.g. Gaussian + Poisson)
  • lme4: frequentist
    • faster
    • simpler interface (??)
    • more convenient outputs
  • other options: glmmTMB, brms

FIXME:

  • sort out random effects tidying
  • set wildtype as baseline level
  • check out convergence warnings with nloptwrap vs bobyqa (why is allFit not working?)